﻿using OnlineMealOrdering.Common;
using OnlineMealOrdering.Domain.Base;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;

namespace OnlineMealOrdering.Domain
{
    public class UserEntity : EntityBase
    {
        public string UserCode { get; set; }

        public string Name { get; set; }

        public string Password { get; set; }

        public EnumAccountType? AccountType { get; set; }

        public string FaceImage { get; set; }

        public string Question { get; set; }

        public string Answer { get; set; }

        public OAuth2TokenEntity AccountToken { get; set; }
        //经度
        public decimal Longitude { get; set; }
        //维度
        public decimal Latitude { get; set; }

        public UserStatus Status { get; set; }

        public DateTime CreateDate { get; set; }

        public virtual ICollection<RoleEntity> Roles { get; set; }

        public virtual ICollection<AddressEntity> Addresss { get; set; }

        public virtual ICollection<PointEntity> Points { get; set; }

        public static UserEntity CreateUser(string userCode, string name, string password, string question, string answer, string area, string address, List<string> roleCodes)
        {
            if (roleCodes == null || roleCodes.Count == 0)
                throw BusinessException.Create("用户的角色不能为空");

            List<RoleEntity> roles = new List<RoleEntity>();
            roleCodes.ForEach(r =>
            {
                var role = DomainContext.Current.EntitySet<RoleEntity>().SingleOrDefault(a => a.RoleCode == r);
                if (role == null)
                    throw BusinessException.Create("角色（编码：{0}）不存在");
                else
                    roles.Add(role);
            }
            );

            var user = DomainContext.Current.EntitySet<UserEntity>().SingleOrDefault(a => a.UserCode == userCode);
            if (user != null)
                throw BusinessException.Create("用户{0},已存在", userCode);

            UserEntity entity = new UserEntity();
            entity.UserCode = userCode;
            entity.Name = name;
            entity.Password = password;
            entity.Roles = new List<RoleEntity>();
            entity.Question = question;
            entity.Answer = answer;
            entity.CreateDate = DateTime.Now;
            var addressEntity = AddressEntity.Create(area, address);
            entity.Addresss = new List<AddressEntity>() { addressEntity };
            entity.AccountType = EnumAccountType.None;
            roles.ForEach(a => entity.Roles.Add(a));

            return entity;
        }

        public static UserEntity CreateOAuth2User(string name, string access_token, string expires_in, string refresh_token, string openid, string openkey, List<string> roleCodes, string faceimage = "")
        {
            if (roleCodes == null || roleCodes.Count == 0)
                throw BusinessException.Create("用户的角色不能为空");
            List<RoleEntity> roles = new List<RoleEntity>();
            roleCodes.ForEach(r =>
            {
                var role = DomainContext.Current.EntitySet<RoleEntity>().SingleOrDefault(a => a.RoleCode == r);
                if (role == null)
                    throw BusinessException.Create("角色（编码：{0}）不存在");
                else
                    roles.Add(role);
            }
            );
            UserEntity entity = new UserEntity();
            entity.UserCode = openid;
            entity.Password = openkey;
            entity.Password = new EncryptHelper().Encrypt(openkey);//把openKey加密保存起来
            entity.Name = name;
            entity.AccountType = EnumAccountType.OAuth2;
            access_token = new EncryptHelper().Encrypt(access_token);
            var token = OAuth2TokenEntity.Create(access_token, expires_in, refresh_token, openid, openkey);
            entity.AccountToken = token;
            entity.Roles = new List<RoleEntity>();
            entity.CreateDate = DateTime.Now;
            entity.FaceImage = faceimage;
            roles.ForEach(a => entity.Roles.Add(a));

            return entity;
        }

        public void SettingUser(string roleCodes, UserStatus status)
        {
            this.Status = status;
            Roles.Clear();
            Roles.Add(DomainContext.Current.EntitySet<RoleEntity>().Single(a => a.RoleCode == roleCodes));

        }

        public void SaveLongitudeLatitude(decimal longitude, decimal latitude)
        {
            this.Longitude = longitude;
            this.Latitude = latitude;
        }

        public void AddPoints(double value, EnumPointType type, int? orderid = null)
        {
            var point = PointEntity.Create(value, type, orderid);
            Points.Add(point);
        }

        public static UserEntity GetUser(int userId)
        {
            return DomainContext.Current.EntitySet<UserEntity>().Single(a => a.Id == userId);
        }
    }
}
